package com.siyoumi.aspect;

import com.siyoumi.annotation.RequestLimit;
import com.siyoumi.component.XRedis;
import com.siyoumi.component.XSpringContext;
import com.siyoumi.exception.EnumSys;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

//限请求数
@Slf4j
@Aspect
@Component
public class AspectRequestLimit {
    protected String getRedisKey(String fix) {
        return "RequestLimit:" + fix;
    }

    @Around("@annotation(requestLimit)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint, RequestLimit requestLimit) throws Throwable {
        log.debug("尝试获取锁时间：{}秒，请求上限1次", requestLimit.second());

        RequestLimitGetKey func = (RequestLimitGetKey) XSpringContext.getBean(requestLimit.key());
        String key = func.getKey(proceedingJoinPoint);
        String redisKey = getRedisKey(key);
        log.debug("key: {}", key);
        log.debug("redis_key: {}", redisKey);

        RLock lock = XRedis.getBean().getLock(redisKey);
        boolean pass = lock.tryLock(requestLimit.second(), TimeUnit.SECONDS); //用1秒尝试获取锁
        if (!pass) { //尝试获取锁
            return EnumSys.LIMIT_MAX_ERROR.getR();
        }
        Object proceed;
        try {
            proceed = proceedingJoinPoint.proceed();
        } catch (Exception ex) {
            throw ex;
        } finally { //解锁
            lock.forceUnlock();
        }
        return proceed;

        //Boolean pass = XRedis.getBean().increment(redisKey, requestLimit.limit(), requestLimit.second());
        //if (!pass) {
        //    return EnumSys.LIMIT_MAX_ERROR.getR();
        //}
        //
        //return proceedingJoinPoint.proceed();
    }
}
